package com.ywz.common;

import cn.hutool.json.JSONException;
import cn.hutool.jwt.JWT;
import cn.hutool.jwt.JWTException;
import cn.hutool.jwt.JWTUtil;
import com.ywz.common.exception.TokenException;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import java.util.Map;

/**
 * 类描述 -> JWT工具类
 *
 * @Author: ywz
 * @Date: 2024/09/18
 */
public class JWTUtils {

    /**
     * 生成token使用的预定义密钥
     */
    private static final String SING = "ywz";

    /**
     * 根据输入的键值对Map生成JWT令牌
     * 该方法主要用于创建一个带有过期时间及指定算法签名的JWT令牌
     *
     * @param map 包含令牌payload数据的键值对Map，其中键为claim名称，值为claim值
     * @return 返回生成的JWT令牌字符串
     */
    public static String getToken(Map<String, Object> map) {
        return JWTUtil.createToken(map, SING.getBytes());
    }

    /**
     * 方法描述 -> 获取token信息方法
     *
     * @param token JWT令牌字符串
     * @throws TokenException 当令牌无效或解析失败时抛出TokenException异常
     * @Author: ywz
     * @Date: 2024/09/18
     */
    public static JWT getTokenInfo(String token) throws TokenException {
        try {
            return JWTUtil.parseToken(token);
        } catch (JWTException | JSONException e) {
            throw new TokenException("非法token");
        } catch (IllegalArgumentException e) {
            throw new TokenException("token为空");
        } catch (Exception e) {
            throw new TokenException("其他token异常");
        }
    }

    /**
     * 方法描述 -> 根据key获取token信息方法
     *
     * @param token JWT令牌字符串
     * @param key 键
     * @return 返回获取的token信息
     * @throws TokenException 当令牌无效或解析失败时抛出TokenException异常
     * @Author: ywz
     * @Date: 2025/02/21
     */
    public static String getTokenInfoByKey(String token, String key) throws TokenException {
        JWT jwt = getTokenInfo(token);
        if (jwt.getPayload(key) == null)
            return null;
        return jwt.getPayload(key).toString();
    }

    /**
     * 方法描述 -> 获取当前登录用户的token信息方法
     * @throws TokenException 当令牌无效或解析失败时抛出TokenException异常
     * @Author: ywz
     * @Date: 2024/10/08
     */
    public static JWT getCurrentTokenInfo() throws TokenException {
        // 获取请求对象
        RequestAttributes ra = RequestContextHolder.getRequestAttributes();
        ServletRequestAttributes sra = (ServletRequestAttributes) ra;
        String token = sra.getRequest().getHeader("token");
        return getTokenInfo(token);
    }

    /**
     * 方法描述 -> 获取当前登录用户的token信息方法
     * @throws TokenException 当令牌无效或解析失败时抛出TokenException异常
     * @param key 键
     * @Author: ywz
     * @Date: 2025/02/21
     */
    public static String getCurrentTokenInfoByKey(String key) throws TokenException {
        JWT jwt = getCurrentTokenInfo();
        if (jwt.getPayload(key) == null)
            return null;
        return jwt.getPayload(key).toString();
    }
}

